<?php
// $Id: template_file.inc,v 1.2 2008/08/15 06:12:26 collectivecolors Exp $
// by Collective Colors - http://collectivecolors.com

/*******************************************************************************
 * Template File
 * 
 * The template file include provides functionality that allows the template api
 * module to load and save files to the filesystem.  This is needed for the css
 * and javascript page injection mechanisms to function correctly. 
 */

//------------------------------------------------------------------------------
// Template File constants (just in case we change the names later)

/**
 * Once again, prefix these constants with ([T]emplate [A]pplication 
 * [P]rograming [I]nterface) so that constants have a much smaller chance of 
 * conflicting with constants defined in the Drupal core and other Drupal 
 * modules.
 */
define('TAPI_ROOT_DIR', file_directory_path() . '/template');
define('TAPI_CSS_DIR',  TAPI_ROOT_DIR . '/css');
define('TAPI_JS_DIR',   TAPI_ROOT_DIR . '/javascript');

/**
 * This module optionally uses a Javascript packer obtained from:
 * 
 * http://joliclic.free.fr/php/javascript-packer/en
 * 
 * Thanks to Nicolas Martin for this great library.
 */
define('TAPI_PACKER_CLASS_FILE', 'class.JavaScriptPacker.php');

/*******************************************************************************
 * Creates all required directories for the template api module if they do not 
 * already exist
 *
 * @return boolean
 */
function template_api_create_template_directories() {

  // Only variables can be passed by reference to Drupals file_check_directory() and we need these
  // constants elsewhere in this file.
  $root_dir = TAPI_ROOT_DIR;
  $css_dir  = TAPI_CSS_DIR;
  $js_dir   = TAPI_JS_DIR;
  
  if (!file_check_directory($root_dir, FILE_CREATE_DIRECTORY))  {
    drupal_set_message('Unable to create or write to a template directory in ' 
                       . file_directory_path());
    $fail = TRUE;
  }
  if (!file_check_directory($css_dir, FILE_CREATE_DIRECTORY)) {
    drupal_set_message('Unable to create or write a css directory in ' . TAPI_ROOT_DIR);
    $fail = TRUE;
  }
  if (!file_check_directory($js_dir, FILE_CREATE_DIRECTORY)) {
    drupal_set_message('Unable to create or write a javascript directory in ' . TAPI_ROOT_DIR);
    $fail = TRUE;
  }
  return $fail ? FALSE : TRUE;
}


/*******************************************************************************
 * Save all template files to the file system
 *
 * This function is meant for internal use only!  The css and javascript
 * parameters are passed by reference to avoid the overhead of having to copy
 * potentially long strings during the normal pass by value php invocation.
 * The css and javascript data is not modified within this function.
 *
 * @param int $tpid - template id number
 * @param string $css_data - css file contents
 * @param string $js_data - javascript file contents
 */
function template_api_save_template_files($tpid, &$css_data, &$js_data) {
	
	// Make sure all the proper directories exist.  This should not have too much
	// of a performance penalty because it is only called when we are saving a 
	// template. 
	if (!template_api_create_template_directories()) {
	  drupal_set_message('Unable to create or write to the needed template directories. '
                       . 'Contact your server administrator if you need assistance.');  
	  return FALSE;
	}
	
	// Save css template file.
	if (strlen($css_data)) {
	  // Compress the CSS file.
	  $css_data = preg_replace('/\/\*.*?\*\//s', '', $css_data); // trim comments
	  $css_data = preg_replace('/\s+/', ' ', $css_data); // condense space
	  $css_data = preg_replace('/\s?(:|;|{|})\s?/', '$1', $css_data);
	}
	$css_path   = TAPI_CSS_DIR . '/id' . $tpid . '.css';
	$css_status = template_api_save_file($css_path, $css_data);
	
	// Save javascript template file.
	if (strlen($js_data)) {
	 $packer_lib = drupal_get_path('module', 'template_api')
	               . '/' . TAPI_PACKER_CLASS_FILE;
	  
	  if (file_exists(realpath($packer_lib))) {
	    // Pack the Javascript file.
	    require_once($packer_lib);
	    
	    $packer  = new JavaScriptPacker($js_data, 'Normal', true, false);
      $js_data = $packer->pack();	    
	  }
	}
	$js_path   = TAPI_JS_DIR  . '/id' . $tpid . '.js';
	$js_status = template_api_save_file($js_path, $js_data);
	
	return ($css_status && $js_status);
}

/*******************************************************************************
 * Save a single template file to the file system
 *
 * This function is meant for internal use only! The file data parameter is 
 * passed by reference to avoid the overhead of having to copy a potentially 
 * long string during the normal pass by value php invocation.
 *
 * @param string $path - file path
 * @param string $data - file contents
 * @return boolean
 */
function template_api_save_file($path, &$data) {
	
  // Save template file.  If we pass an empty string for the data parameter and 
  // this file exists already then we assume that the existing file is to be 
  // deleted.
  if (strlen($data)) {
    // Got data. Save template file.
    if (!file_save_data($data, $path, FILE_EXISTS_REPLACE)) {
		  return template_api_log_status('File "' . $path . '" save failed', 
		                                 WATCHDOG_ERROR);		
	  }
	  else {
		  return template_api_log_status('File "' . $path . '" saved successfully');
	  }
  }
  else {
    // No data. Delete existing template file.
    return template_api_delete_file($path);  
  }
}

/*******************************************************************************
 * Delete all template files from the file system if they exist
 *
 * This function is meant for internal use only!
 *
 * @param int $tpid - template id number
 * @return boolean
 */
function template_api_delete_template_files($tpid) {
		
	// Delete css file if it exists.
	$css_path   = TAPI_CSS_DIR . '/id' . $tpid . '.css';
	$css_status = template_api_delete_file($css_path);
		
	// Delete javascript file if it exists.
	$js_path   = TAPI_JS_DIR . '/id' . $tpid . '.js';
	$js_status = template_api_delete_file($js_path);
	
	return ($css_status && $js_status);
}

/*******************************************************************************
 * Delete a single template file from the file system
 *
 * This function is meant for internal use only!
 *
 * @param string $path - file path
 * @return boolean
 */
function template_api_delete_file($path) {

  if (file_exists($path)) {
    // File exists.  Delete me!!!
	  if (!file_delete($path)) {
	    return template_api_log_status('File "' . $path . '" delete failed', 
		                                 WATCHDOG_ERROR);
	  }
	  else {
	    return template_api_log_status('File "' . $path 
	                                   . '" deleted successfully');  
	  }
	}
	// File does not exist.
	return TRUE;
}

/*******************************************************************************
 * Load a template files contents into memory
 *
 * This function is meant for internal use only!  Currently this function is 
 * not used.  It is defined only for completeness.  In fact, I don't know why I 
 * would need this file eventually because the files are meant to be compressed
 * so the readable file contents get loaded from the database.  But I've already
 * defined it and we never know when we may need it, so here it is.
 *
 * @param string $path - file path
 * @return string - file data
 */
function template_api_load_file($path) {
	$real_path = realpath($path);
	
	// If there is no file then just return an empty string.  We do not want
	// warnings if the file does not exist.
	if (!file_exists($real_path)) {
		return '';
	}
	// File exists. Load em up.
	return file_get_contents($real_path);
}

/*******************************************************************************
 * Inject template files into the html page header
 *
 * @param int $tpid - template id number
 */
function template_api_inject_files($tpid) {
  // Inject template css file into the html page header.
  $css_path = TAPI_CSS_DIR . '/id' . $tpid . '.css';
	if (file_exists($css_path) && filesize($css_path) > 0) {
		drupal_add_css($css_path, 'theme');
	}
	
	// Inject template javascript file into the html page header.
	$js_path  = TAPI_JS_DIR . '/id' . $tpid . '.js';
	if (file_exists($js_path) && filesize($js_path) > 0) {
		drupal_add_js($js_path, 'theme');
	}	
}